package models

import (
	"time"
)

// 漏洞严重程度
type Severity string

const (
	SeverityCritical Severity = "critical" // 严重
	SeverityHigh     Severity = "high"     // 高危
	SeverityMedium   Severity = "medium"   // 中危
	SeverityLow      Severity = "low"      // 低危
	SeverityInfo     Severity = "info"     // 信息
)

// 漏洞状态
type VulnStatus string

const (
	StatusNew           VulnStatus = "new"            // 新发现
	StatusVerified      VulnStatus = "verified"       // 已验证
	StatusInProgress    VulnStatus = "in_progress"    // 修复中
	StatusFixed         VulnStatus = "fixed"          // 已修复
	StatusClosed        VulnStatus = "closed"         // 已关闭
	StatusFalsePositive VulnStatus = "false_positive" // 误报
)

// 漏洞类型
type VulnType string

const (
	TypeSQLInjection       VulnType = "sql_injection"       // SQL注入
	TypeXSS                VulnType = "xss"                 // 跨站脚本
	TypeCmdInjection       VulnType = "cmd_injection"       // 命令注入
	TypeSSRF               VulnType = "ssrf"                // 服务器端请求伪造
	TypeFileUpload         VulnType = "file_upload"         // 文件上传
	TypeFileInclusion      VulnType = "file_inclusion"      // 文件包含
	TypeInfoDisclosure     VulnType = "info_disclosure"     // 信息泄露
	TypeUnauthorizedAccess VulnType = "unauthorized_access" // 未授权访问
	TypeWeakPassword       VulnType = "weak_password"       // 弱密码
	TypeMisconfig          VulnType = "misconfiguration"    // 错误配置
	TypeOther              VulnType = "other"               // 其他
)

// Vulnerability 漏洞模型
type Vulnerability struct {
	ID               uint       `json:"id" gorm:"primary_key"`
	Title            string     `json:"title" gorm:"type:varchar(255);not null"`
	CVE              string     `json:"cve" gorm:"type:varchar(50);index"`
	Description      string     `json:"description" gorm:"type:text"`
	Type             VulnType   `json:"type" gorm:"type:varchar(30);not null;default:'other'"` // 漏洞类型
	Severity         Severity   `json:"severity" gorm:"type:varchar(20);not null"`
	Status           VulnStatus `json:"status" gorm:"type:varchar(20);not null"`
	References       string     `json:"references" gorm:"type:text"`
	Solution         string     `json:"solution" gorm:"type:text"`
	StepsToReproduce string     `json:"steps_to_reproduce" gorm:"type:text"` // 重现步骤
	Vector           string     `json:"vector" gorm:"type:varchar(255)"`
	CVSS             float64    `json:"cvss" gorm:"type:float"`
	Assets           []Asset    `json:"assets" gorm:"many2many:vulnerability_assets;"`
	Source           string     `json:"source" gorm:"type:varchar(50)"` // 漏洞来源，如：scan、manual、jenkins、gitlab等
	Notes            string     `json:"notes" gorm:"type:text"`         // 额外备注信息
	ReportedBy       uint       `json:"reported_by" gorm:"type:int"`    // 报告人ID
	DiscoveredAt     time.Time  `json:"discovered_at"`                  // 发现时间
	VerifiedAt       *time.Time `json:"verified_at"`                    // 验证时间
	FixedAt          *time.Time `json:"fixed_at"`                       // 修复时间
	ClosedAt         *time.Time `json:"closed_at"`                      // 关闭时间
	CreatedAt        time.Time  `json:"created_at"`
	UpdatedAt        time.Time  `json:"updated_at"`
	DeletedAt        *time.Time `json:"-" gorm:"index"`
}

// TableName 指定表名
func (Vulnerability) TableName() string {
	return "vulnerabilities"
}

// IsCritical 判断是否为严重漏洞
func (v *Vulnerability) IsCritical() bool {
	return v.Severity == SeverityCritical
}

// IsFixed 判断是否已修复
func (v *Vulnerability) IsFixed() bool {
	return v.Status == StatusFixed || v.Status == StatusClosed
}

// SetVerified 设置为已验证
func (v *Vulnerability) SetVerified() {
	v.Status = StatusVerified
	now := time.Now()
	v.VerifiedAt = &now
}

// SetFixed 设置为已修复
func (v *Vulnerability) SetFixed() {
	v.Status = StatusFixed
	now := time.Now()
	v.FixedAt = &now
}

// SetClosed 设置为已关闭
func (v *Vulnerability) SetClosed() {
	v.Status = StatusClosed
	now := time.Now()
	v.ClosedAt = &now
}

// MarkAsVerified 将漏洞标记为已验证
func (v *Vulnerability) MarkAsVerified() {
	v.Status = StatusVerified
	now := time.Now()
	v.VerifiedAt = &now
	v.UpdatedAt = now
}

// MarkAsFixed 将漏洞标记为已修复
func (v *Vulnerability) MarkAsFixed() {
	v.Status = StatusFixed
	now := time.Now()
	v.FixedAt = &now
	v.UpdatedAt = now
}

// MarkAsClosed 将漏洞标记为已关闭
func (v *Vulnerability) MarkAsClosed() {
	v.Status = StatusClosed
	now := time.Now()
	v.ClosedAt = &now
	v.UpdatedAt = now
}
